﻿using DA6502.Controls;

//  此文件中定义CPU的一些行为
namespace DA6502.CPU
{
    using addr = System.UInt16;

    public partial class CPU
    {
        /// <summary>
        /// CPU总线
        /// </summary>
        protected MemoryView IO;

        /// <summary>
        /// HALT状态标记。执行KIL（也称HLT、JAM）。
        /// 机器码为02, 12, 22, 32, 42, 52, 62, 72, 92, B2, D2, F2
        /// 执行此指令将结束CPU运行，除非RESET
        /// </summary>
        protected bool kilFlag = false;

        protected delegate int CommandHandler();

        protected CommandHandler[] commands;

        /// <summary>
        /// CPU时钟周期到来
        /// </summary>
        public void OnClock()
        {

            //  查验RstFlag以决定是否启动Rst中断
            if (rstFlag) OnInterruptReset();

            if (!kilFlag)
            {
                //  1.查看是否有中断需要处理
                //  IRQ
                if ((!I) && irqFlag) OnInterruptIRQ();

                //  2.NMI
                if (nmiFlag) OnInterruptNMI();

                ushort oldpc = PC;
                //  3.取指               
                currOpCod = IF();

                //  4.执行
                Execute(currOpCod);
            }
        }

        //  设置各个CPU指令用到的委托（函数指针）
        private void FillCommandList()
        {
            //  指向所有CPU指令的委托
            commands = new CommandHandler[]
            {
                Cmd00,Cmd01,Cmd02,Cmd03,Cmd04,Cmd05,Cmd06,Cmd07,Cmd08,Cmd09,Cmd0A,Cmd0B,Cmd0C,Cmd0D,Cmd0E,Cmd0F,
                Cmd10,Cmd11,Cmd12,Cmd13,Cmd14,Cmd15,Cmd16,Cmd17,Cmd18,Cmd19,Cmd1A,Cmd1B,Cmd1C,Cmd1D,Cmd1E,Cmd1F,
                Cmd20,Cmd21,Cmd22,Cmd23,Cmd24,Cmd25,Cmd26,Cmd27,Cmd28,Cmd29,Cmd2A,Cmd2B,Cmd2C,Cmd2D,Cmd2E,Cmd2F,
                Cmd30,Cmd31,Cmd32,Cmd33,Cmd34,Cmd35,Cmd36,Cmd37,Cmd38,Cmd39,Cmd3A,Cmd3B,Cmd3C,Cmd3D,Cmd3E,Cmd3F,
                Cmd40,Cmd41,Cmd42,Cmd43,Cmd44,Cmd45,Cmd46,Cmd47,Cmd48,Cmd49,Cmd4A,Cmd4B,Cmd4C,Cmd4D,Cmd4E,Cmd4F,
                Cmd50,Cmd51,Cmd52,Cmd53,Cmd54,Cmd55,Cmd56,Cmd57,Cmd58,Cmd59,Cmd5A,Cmd5B,Cmd5C,Cmd5D,Cmd5E,Cmd5F,
                Cmd60,Cmd61,Cmd62,Cmd63,Cmd64,Cmd65,Cmd66,Cmd67,Cmd68,Cmd69,Cmd6A,Cmd6B,Cmd6C,Cmd6D,Cmd6E,Cmd6F,
                Cmd70,Cmd71,Cmd72,Cmd73,Cmd74,Cmd75,Cmd76,Cmd77,Cmd78,Cmd79,Cmd7A,Cmd7B,Cmd7C,Cmd7D,Cmd7E,Cmd7F,
                Cmd80,Cmd81,Cmd82,Cmd83,Cmd84,Cmd85,Cmd86,Cmd87,Cmd88,Cmd89,Cmd8A,Cmd8B,Cmd8C,Cmd8D,Cmd8E,Cmd8F,
                Cmd90,Cmd91,Cmd92,Cmd93,Cmd94,Cmd95,Cmd96,Cmd97,Cmd98,Cmd99,Cmd9A,Cmd9B,Cmd9C,Cmd9D,Cmd9E,Cmd9F,
                CmdA0,CmdA1,CmdA2,CmdA3,CmdA4,CmdA5,CmdA6,CmdA7,CmdA8,CmdA9,CmdAA,CmdAB,CmdAC,CmdAD,CmdAE,CmdAF,
                CmdB0,CmdB1,CmdB2,CmdB3,CmdB4,CmdB5,CmdB6,CmdB7,CmdB8,CmdB9,CmdBA,CmdBB,CmdBC,CmdBD,CmdBE,CmdBF,
                CmdC0,CmdC1,CmdC2,CmdC3,CmdC4,CmdC5,CmdC6,CmdC7,CmdC8,CmdC9,CmdCA,CmdCB,CmdCC,CmdCD,CmdCE,CmdCF,
                CmdD0,CmdD1,CmdD2,CmdD3,CmdD4,CmdD5,CmdD6,CmdD7,CmdD8,CmdD9,CmdDA,CmdDB,CmdDC,CmdDD,CmdDE,CmdDF,
                CmdE0,CmdE1,CmdE2,CmdE3,CmdE4,CmdE5,CmdE6,CmdE7,CmdE8,CmdE9,CmdEA,CmdEB,CmdEC,CmdED,CmdEE,CmdEF,
                CmdF0,CmdF1,CmdF2,CmdF3,CmdF4,CmdF5,CmdF6,CmdF7,CmdF8,CmdF9,CmdFA,CmdFB,CmdFC,CmdFD,CmdFE,CmdFF
            };
        }

        /// <summary>
        /// 执行一个CPU指令
        /// </summary>
        /// <param name="cmd">指令码</param>
        /// <returns>CPU执行此指令所需要的周期数</returns>
        public int Execute(byte cmd)
        {
            return commands[cmd]();
        }

        /// <summary>
        /// 将程序指针设为PC，然后执行一个指令
        /// </summary>
        /// <param name="cmd">指令</param>
        /// <param name="pc">程序指针</param>
        /// <returns></returns>
        public int Execute(byte cmd, addr pc)
        {
            PC = pc;
            return Execute(cmd);
        }

        /// <summary>
        /// 将寄存器状态设置为reg后执行指令
        /// </summary>
        /// <param name="cmd">指令</param>
        /// <param name="reg">寄存器状态</param>
        /// <returns>CPU执行此指令所需要的周期数</returns>
        public int Execute(byte cmd, Registers reg)
        {
            reg.ReleaseRegisters(this);
            return Execute(cmd);
        }
    }
}